package com.xuecheng.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.base.exception.StudySystemException;
import com.xuecheng.base.model.PageResult;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.learning.feignclient.ContentServiceClient;
import com.xuecheng.learning.mapper.XcChooseCourseMapper;
import com.xuecheng.learning.mapper.XcCourseTablesMapper;
import com.xuecheng.learning.model.dto.MyCourseTableParams;
import com.xuecheng.learning.model.dto.XcChooseCourseDto;
import com.xuecheng.learning.model.dto.XcCourseTablesDto;
import com.xuecheng.learning.model.po.XcChooseCourse;
import com.xuecheng.learning.model.po.XcCourseTables;
import com.xuecheng.learning.service.MyCourseTableService;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * @author Tang
 * @version 1.0
 * @date 2024/1/12 17:14
 */
@Service
@Slf4j
public class MyCourseTableServiceImpl implements MyCourseTableService {
    @Autowired
    XcChooseCourseMapper xcChooseCourseMapper;
    @Autowired
    XcCourseTablesMapper xcCourseTablesMapper;
    @Autowired
    ContentServiceClient contentServiceClient;
    private final static String GRATIS = "201000";
    private final static String GRATIS_COURSE = "700001";
    /** 选课成功 **/
    private final static String CHOOSE_COURSE_STATE_SUCCESS = "701001";
    private final static String FEE_BASE_COURSES = "700002";
    /** 待支付 **/
    private final static String WITH_PAYMENT = "701002";
    private final static String NO_CHOOSE_COURSE = "702002";
    private final static String EXPIRED = "702003";
    private final static String NORMAL_LEARNING = "702001";
    @Override
    @Transactional
    public XcChooseCourseDto addChooseCourse(String userId, Long courseId) {
        CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId);
        if (Objects.isNull(coursepublish)) {
            StudySystemException.cast("课程不存在");
        }
        String charge = coursepublish.getCharge();
        // 免费课程
        XcChooseCourse xcChooseCourse = null;
        if (GRATIS.equals(charge)) {
            xcChooseCourse = addFreeCoruse(userId, coursepublish);
            addCourseTabls(xcChooseCourse);
        } else {
            xcChooseCourse = addChargeCoruse(userId, coursepublish);
        }
        XcChooseCourseDto xcChooseCourseDto = new XcChooseCourseDto();
        // 获取学生学习资格
        XcCourseTablesDto learningState = getLearningState(userId, courseId);
        BeanUtils.copyProperties(learningState, xcChooseCourseDto);
        xcChooseCourseDto.setLearnStatus(learningState.getLearnStatus());
        learningState = null;
        xcChooseCourseDto.setCoursePrice(coursepublish.getPrice());
        xcChooseCourseDto.setId(xcChooseCourse.getId());
        xcChooseCourseDto.setCourseId(xcChooseCourse.getCourseId());
        xcChooseCourseDto.setCourseName(xcChooseCourse.getCourseName());
        return xcChooseCourseDto;
    }

    @Override
    public XcCourseTablesDto getLearningState(String userid, Long courseId) {
        XcCourseTables xcCourseTables = getXcCourseTables(userid, courseId);
        XcCourseTablesDto xcCourseTablesDto = new XcCourseTablesDto();
        if (Objects.isNull(xcCourseTables)) {
            xcCourseTablesDto.setLearnStatus(NO_CHOOSE_COURSE);
            return xcCourseTablesDto;
        }
        boolean before = xcCourseTables.getValidtimeEnd().isBefore(LocalDateTime.now());
        BeanUtils.copyProperties(xcCourseTables, xcCourseTablesDto);
        if (before) {
            xcCourseTablesDto.setLearnStatus(EXPIRED);
            return xcCourseTablesDto;
        }
        xcCourseTablesDto.setLearnStatus(NORMAL_LEARNING);
        return xcCourseTablesDto;
    }

    @Override
    public boolean saveChooseCourseSuccess(String chooseCourseId) {
        // 感觉选课id查询选课表
        XcChooseCourse chooseCourse = xcChooseCourseMapper.selectById(chooseCourseId);
        if (Objects.isNull(chooseCourse)) {
            log.debug("接收到购买课程消息, 根据选课id从数据库查询不到记录, 选课id:{}", chooseCourseId);
            return false;
        }
        String status = chooseCourse.getStatus();
        // 待支付更新为已支付
        if (WITH_PAYMENT.equals(status)) {
            chooseCourse.setStatus(CHOOSE_COURSE_STATE_SUCCESS);
            int update = xcChooseCourseMapper.updateById(chooseCourse);
            if (update < 0) {
                log.debug("更新选课状态失败, message:{}", chooseCourse);
                StudySystemException.cast("更新选课状态失败");
                addCourseTabls(chooseCourse);
            }
        }
        return true;
    }

    @Override
    public PageResult<XcCourseTables> mycoursetable(MyCourseTableParams params) {
        Page<XcCourseTables> page = new Page<>(params.getPage(), params.getSize());
        Page<XcCourseTables> result = xcCourseTablesMapper.selectPage(page, new LambdaQueryWrapper<XcCourseTables>()
                .eq(XcCourseTables::getUserId, params.getUserId()));
        return new PageResult<>(result.getRecords(),
                result.getTotal(), params.getPage(),
                params.getSize());
    }

    // 添加收费课程 addChargeCoruse
    public XcChooseCourse addChargeCoruse(String userId, @NotNull CoursePublish coursepublish) {
        List<XcChooseCourse> courseList = xcChooseCourseMapper.selectList(new LambdaQueryWrapper<XcChooseCourse>()
                .eq(XcChooseCourse::getUserId, userId)
                .eq(XcChooseCourse::getCourseId, coursepublish.getId())
                .eq(XcChooseCourse::getOrderType, FEE_BASE_COURSES)
                .eq(XcChooseCourse::getStatus, WITH_PAYMENT));
        if (courseList.size() > 0) {
            return courseList.get(0);
        }
        XcChooseCourse chooseCourse = new XcChooseCourse();
        chooseCourse.setCourseId(coursepublish.getId());
        chooseCourse.setUserId(userId);
        chooseCourse.setCourseName(coursepublish.getName());
        chooseCourse.setCompanyId(coursepublish.getCompanyId());
        chooseCourse.setOrderType(FEE_BASE_COURSES);
        chooseCourse.setCreateDate(LocalDateTime.now());
        chooseCourse.setCoursePrice(coursepublish.getPrice());
        chooseCourse.setValidDays(365);
        chooseCourse.setStatus(WITH_PAYMENT);
        chooseCourse.setValidtimeStart(LocalDateTime.now());
        chooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(chooseCourse.getValidDays()));
        int insert = xcChooseCourseMapper.insert(chooseCourse);
        if (insert <= 0) {
            StudySystemException.cast("添加选课记录失败");
        }
        return chooseCourse;
    }

    // 添加免费课程,免费课程加入选课记录表、我的课程表 addFreeCoruse
    public XcChooseCourse addFreeCoruse(String userId, CoursePublish coursepublish){
        // 如果存在收费课程
        List<XcChooseCourse> courseList = xcChooseCourseMapper.selectList(new LambdaQueryWrapper<XcChooseCourse>()
                .eq(XcChooseCourse::getUserId, userId)
                .eq(XcChooseCourse::getCourseId, coursepublish.getId())
                .eq(XcChooseCourse::getOrderType, GRATIS_COURSE)
                .eq(XcChooseCourse::getStatus, CHOOSE_COURSE_STATE_SUCCESS));
        if (courseList.size() > 0) {
            return courseList.get(0);
        }
        XcChooseCourse chooseCourse = new XcChooseCourse();
        chooseCourse.setCourseId(coursepublish.getId());
        chooseCourse.setUserId(userId);
        chooseCourse.setCourseName(coursepublish.getName());
        chooseCourse.setCompanyId(coursepublish.getCompanyId());
        chooseCourse.setOrderType(GRATIS_COURSE);
        chooseCourse.setCreateDate(LocalDateTime.now());
        chooseCourse.setCoursePrice(coursepublish.getPrice());
        chooseCourse.setValidDays(365);
        chooseCourse.setStatus(CHOOSE_COURSE_STATE_SUCCESS);
        chooseCourse.setValidtimeStart(LocalDateTime.now());
        chooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(chooseCourse.getValidDays()));
        int insert = xcChooseCourseMapper.insert(chooseCourse);
        if (insert <= 0) {
            StudySystemException.cast("添加选课记录失败");
        }
        return chooseCourse;
    }
    //添加到我的课程表
    public XcCourseTables addCourseTabls(XcChooseCourse xcChooseCourse){
        String status = xcChooseCourse.getStatus();
        if (!CHOOSE_COURSE_STATE_SUCCESS.equals(status)) {
            StudySystemException.cast("选课没有成功，无法添加到课程表");
        }
        XcCourseTables xcCourseTables = getXcCourseTables(xcChooseCourse.getUserId(), xcChooseCourse.getCourseId());
        if (!Objects.isNull(xcCourseTables)) {
            return xcCourseTables;
        }
        XcCourseTables courseTables = new XcCourseTables();
        BeanUtils.copyProperties(xcChooseCourse, courseTables);
        // 记录选课表的主键
        courseTables.setChooseCourseId(xcChooseCourse.getId());
        courseTables.setCourseType(xcChooseCourse.getOrderType());
        courseTables.setUpdateDate(LocalDateTime.now());
        int insert = xcCourseTablesMapper.insert(courseTables);
        if (insert <= 0) {
            StudySystemException.cast("添加课程表失败");
        }
        return courseTables;
    }

    public XcCourseTables getXcCourseTables(String userId,Long courseId){
        return xcCourseTablesMapper.selectOne(new LambdaQueryWrapper<XcCourseTables>()
                .eq(XcCourseTables::getUserId, userId)
                .eq(XcCourseTables::getCourseId, courseId));
    }
}
